#ifndef BUFFER_H
#define BUFFER_H
#include "malloc.h"
#include <strings.h>
#include <string.h>
#include <vector>
#include <sys/uio.h>
#include <arpa/inet.h>
#include <iostream>
#include "HttpRequest.hpp"

// class HttpRequest;
class Buffer {
public:

    Buffer(int size);
    ~Buffer();
    void extendRoom(int size); // 扩容
    inline int writableSize() {
        // 还有多少地方可以写数据
        return capacity_ - writePos_;
    }
    inline int readableSize() {
        // 还有多少数据没有取出来
        return writePos_ - readPos_;
    }

    int appendString(const char* data, int size); // 向写数据区添加数据
    int appendString(const char* data);

    template <typename T>
    T getData(size_t size) {
        if (size < 0) {
            return T ();
        }
        int readable = readableSize();
        if (size > readable) {
            size = readable;
        }
        T result(data_+readPos_, data_+readPos_+size);
        readPos_ += size;
        return result;
    }

    template <typename T>
    T getData(){
        return getData<T>(readableSize());
    }

    template <typename T>
    T getSplit(const char* needle, int needleSize) {
        char* ptr = static_cast<char*>(memmem(data_+readPos_, readableSize(), needle, needleSize));
        if (ptr == NULL) {
            return T(data_+readPos_, data_+readPos_+readableSize());
        }
        T result(data_+readPos_, ptr);
        readPos_ = ptr - data_ + needleSize;
        return result;
    }

    


    inline bool empty(){
        // 表示没有任何未读的数据在缓冲区
        return readableSize() == 0;
    }

    
    int socketRead(int fd); // 将fd中的数据读取到写数据区
    
    int sendData(int socket); // 将剩余数据发送到socket


    void printBuff(){
        for (char* i=data_; i < data_+writePos_; ++i){
            std::cout << *i ;
        }
        std::cout << std::endl;
    }

private:
    char* data_;
    int capacity_;
    int readPos_ = 0;
    int writePos_ = 0;
    

public:
    const char* findCRLF(const char* needle, int needleSize);
    inline const char* getReadPos() {
        return data_ + readPos_;
    }

    inline const char* getWritePos() {
        return data_+writePos_;
    }

    inline const char* getBufferStart() {
        return data_;
    }
    
};

#endif